package com.geese.module.admin.service.impl;

import com.geese.common.constants.BusinessConstants;
import com.geese.common.constants.Constants;
import com.geese.common.entity.*;
import com.geese.common.util.PageUtil;
import com.geese.common.vo.Page;
import com.geese.common.vo.Paginator;
import com.geese.exception.BusinessException;
import com.geese.module.admin.service.ICashService;
import com.geese.module.admin.vo.CashVO;
import com.geese.module.admin.vo.CeoQuery;
import com.geese.module.ceo.dao.*;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * Created by huweiwei on 2017/3/20.
 */
@Service
public class CashServiceImpl implements ICashService {

    @Autowired
    private CashMapper cashMapper;
    @Autowired
    private CourierMapper courierMapper;
    @Autowired
    private SchoolMapper schoolMapper;
    @Autowired
    private CampusMapper campusMapper;
    @Autowired
    private BuildingMapper buildingMapper;


    @Override
    public Map<String, Object> getList(Page page, CashVO cashVO) {
        PageHelper.startPage(page.getCurrPage(), page.getPageSize(), " id DESC");
        List<Cash> cashList = cashMapper.getAll(cashVO);
        List<Map<String, Object>> data = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(cashList)) {
            List<Integer> courierIds = Lists.transform(cashList, new Function<Cash, Integer>() {
                @Override
                public Integer apply(Cash cash) {
                    return cash.getCourierId();
                }
            });
            List<Courier> courierList = courierMapper.selectByIdsIgnoreDel(courierIds);
            Map<Integer, Courier> courierMap = Maps.uniqueIndex(courierList, new Function<Courier, Integer>() {
                @Override
                public Integer apply(Courier courier) {
                    return courier.getId();
                }
            });

            List<Courier> ceoList = courierMapper.listCeoByQuery(new CeoQuery());
            Map<Integer, Courier> ceoMap = Maps.uniqueIndex(ceoList, new Function<Courier, Integer>() {
                @Override
                public Integer apply(Courier courier) {
                    return courier.getSchoolId();
                }
            });

            List<Integer> schoolIds = Lists.transform(courierList, new Function<Courier, Integer>() {
                @Override
                public Integer apply(Courier courier) {
                    return courier.getSchoolId();
                }
            });
            List<Integer> campusIds = Lists.transform(courierList, new Function<Courier, Integer>() {
                @Override
                public Integer apply(Courier courier) {
                    return courier.getCampusId();
                }
            });
            List<Integer> buildingIds = Lists.transform(courierList, new Function<Courier, Integer>() {
                @Override
                public Integer apply(Courier courier) {
                    return courier.getBuildingId();
                }
            });
            List<School> schools = schoolMapper.listAllBySet(Sets.newHashSet(schoolIds));
            List<Campus> campuses = campusMapper.listAllBySet(Sets.newHashSet(campusIds));
            List<Building> buildings = buildingMapper.listAllBySet(Sets.newHashSet(buildingIds));

            Map<Integer, School> schoolMap = Maps.uniqueIndex(schools, new Function<School, Integer>() {
                @Override
                public Integer apply(School school) {
                    return school.getId();
                }
            });
            Map<Integer, Campus> campusMap = Maps.uniqueIndex(campuses, new Function<Campus, Integer>() {
                @Override
                public Integer apply(Campus campus) {
                    return campus.getId();
                }
            });
            Map<Integer, Building> buildingMap = Maps.uniqueIndex(buildings, new Function<Building, Integer>() {
                @Override
                public Integer apply(Building building) {
                    return building.getId();
                }
            });
            StringBuffer sb = new StringBuffer();
            for (Cash cash : cashList) {
                Integer courierId = cash.getCourierId();
                sb.setLength(0);
                sb.append(schoolMap.get(courierMap.get(courierId).getSchoolId()).getName())
                  .append("-")
                  .append(campusMap.get(courierMap.get(courierId).getCampusId()).getName())
                  .append("-")
                  .append(buildingMap.get(courierMap.get(courierId).getBuildingId()).getName());
                Map<String, Object> temp = Maps.newHashMap();
                temp.put("id", cash.getId());
                temp.put("oid", cash.getOid());
                temp.put("courierId", cash.getCourierId());
                temp.put("courierName", cash.getCourierName());
                temp.put("courierMobile", cash.getCourierMobile());
                temp.put("courierAccountType", cash.getAccountType());
                temp.put("courierAccount", cash.getAccount());
                temp.put("ceo", ceoMap.get(courierMap.get(courierId).getSchoolId()).getName());
                temp.put("address", sb.toString());
                temp.put("ceoMobile", ceoMap.get(courierMap.get(courierId).getSchoolId()).getMobile());
                temp.put("applyTime", cash.getApplyTime());
                temp.put("confirmTime", cash.getConfirmTime());
                temp.put("amount", cash.getAmount());
                temp.put("status", cash.getStatus());
                data.add(temp);
            }
        }
        Paginator<Cash> cashPaginator =  PageUtil.getPage(cashList);
        Map<String, Object> result = Maps.newHashMap();
        result.put(Constants.PAGE_INFO, cashPaginator.getPageResult());
        result.put("cashList", data);
        return result;
    }

    @Override
    public void delete(int id) {
        cashMapper.deleteCash(id);
    }

    @Override
    public void batchDelete(List<Integer> ids) {
        cashMapper.deleteBatch(ids);
    }

    @Override
    public Integer doAudit(int id) {
        Cash cash = cashMapper.findById(id);
        if (cash == null) {
            throw new BusinessException(120120);
        }
        if (cash.getStatus() != 0) {
            throw new BusinessException(120121);
        }
        cash.setStatus(BusinessConstants.CASH_STATUS_AUDIT);
        cashMapper.updateCash(cash);
        return cash.getOid();
    }

    @Override
    public List<Integer> batchAudit(List<Integer> ids) {
        List<Cash> cashes = cashMapper.selectListByIds(ids);
        List<Integer> checkIds = Lists.newArrayList();
        for (Cash cash : cashes) {
            if (cash.getStatus() != 0) {
                throw new BusinessException(120121);
            }
            checkIds.add(cash.getId());
        }
        if (cashes.size() != checkIds.size()) {
            throw new BusinessException(120009);
        }
        cashMapper.updateStatusByIds(BusinessConstants.CASH_STATUS_AUDIT, checkIds);
        return Lists.transform(cashes, new Function<Cash, Integer>() {
            @Override
            public Integer apply(Cash cash) {
                return cash.getOid();
            }
        });
    }

    @Override
    public Integer doComplete(int id) {
        Cash cash = cashMapper.findById(id);
        if (cash == null) {
            throw new BusinessException(120099);
        }
//        Courier courier = courierMapper.findById(cash.getCourierId());
//        if (courier == null) {
//            throw new BusinessException(120100);
//        }
//        courier.setAmount(courier.getAmount() - cash.getAmount());
//        courierMapper.update(courier);

        cash.setStatus(BusinessConstants.CASH_STATUS_COMPLETE);
        cashMapper.updateCash(cash);
        return cash.getOid();
    }

    @Override
    public List<Integer> batchComplete(List<Integer> ids) {
        List<Integer> oidList = Lists.newArrayList();
        for (Integer id : ids) {
            oidList.add(doComplete(id));
        }
        return oidList;
    }
}
